package com.wlza.sign;

import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONObject;
import com.wlza.utils.Constant;

import java.util.HashMap;
import java.util.Map;

// 加解密服务
public class EncryptService {
    private static KeyCodeInfo __cryptoKey;
    private final JiDaUtilService jiDaUtilService = JiDaUtilService.getInstance();
    private final CryptoConfiguration cryptoConfig = CryptoConfiguration.getInstance();

    private static volatile EncryptService instance;

    private EncryptService() {
    }

    // 加密
    public String encrypt(String str) {
        String keyCode = getKeyCode();
        String encryptUrl = cryptoConfig.getBaseUrl() + cryptoConfig.getEncryptUri();

        Map<String, String> reqHeaders = jiDaUtilService.getReqHeaders();

        Map<String, Object> reqBody = new HashMap<>();
        reqBody.put("keyCode", keyCode);
        reqBody.put("algorithmParam", "SM4/ECB/PKCS7Padding");
        reqBody.put("data", Base64.encode(str));
        JSONObject respBody = jiDaUtilService.sendPostReq(reqHeaders, reqBody, encryptUrl);
        JSONObject data = respBody.getJSONObject("data");
        return data.getStr("encData");
    }

    public static EncryptService getInstance() {
        if (instance == null) {
            synchronized (EncryptService.class) {
                if (instance == null) {
                    instance = new EncryptService();
                }
            }
        }
        return instance;
    }

    private String getKeyCode() {
        // 内存中存在密钥且未过期则直接返回
        if (__cryptoKey != null && __cryptoKey.getExpirationTime().after(new java.util.Date())) {
            return __cryptoKey.getKeyCode();
        }
        // 内存不存在则创建
        if (__cryptoKey == null) {
            // 2.1.1 没有密钥则从密钥服务器获取密钥
            __cryptoKey = jiDaUtilService.getKeyCodeFromServer("SM4", 128, "0");
            __cryptoKey.setUsage(Constant.CRYPTO);
            // 2.1.2保存密钥到内存
            return __cryptoKey.getKeyCode();
        }
        // 内存存在但已过期则延长秘钥有效期
        if (__cryptoKey.getExpirationTime().before(new java.util.Date())) {
            __cryptoKey = jiDaUtilService.extendKeyCodeExpirationTime(__cryptoKey);
        }
        return __cryptoKey.getKeyCode();
    }


}
